home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part2 / 15515 < prev    next >
Encoding:
Text File  |  1996-08-05  |  2.6 KB  |  85 lines

  1. Path: news.rchland.ibm.com!usenet
  2. From: Philip Staite <pstaite+@rchland.ibm.com>
  3. Newsgroups: comp.lang.c++
  4. Subject: Re: inheritance of friendship
  5. Date: Fri, 05 Apr 1996 16:18:26 -0600
  6. Organization: IBM Rochester, MN
  7. Message-ID: <31659C32.41C6@rchland.ibm.com>
  8. References: <4k3ge2$igu@panoramix.fi.upm.es>
  9. NNTP-Posting-Host: powertool.rchland.ibm.com
  10. Mime-Version: 1.0
  11. Content-Type: text/plain; charset=us-ascii
  12. Content-Transfer-Encoding: 7bit
  13. X-Mailer: Mozilla 2.01 (X11; I; AIX 1)
  14.  
  15. Sacha wrote:
  16. > I've just read in the FAQ that friendship isn't inherited: that is if B is a
  17. > friend of class A, and class C is derived from B, C ISN'T a friend of A.
  18. >         A     friends with B
  19. >                            |
  20. >           not friends with C
  21. > Is there some way around this?
  22. > I am overloading << to output to streams, but I don't want to have to rewrite the
  23. > same function for each different type of stream. I've tried making both B and C
  24. > friends of A and defining the function for B, but this doesn't work.
  25. > Should I just forget about overloading << and write an outToStream function
  26. > instead?
  27.  
  28. I'm not sure exactly what you're trying to do, but here are a couple of
  29. examples of what you _can_ do...
  30.  
  31.  
  32. class foo {
  33.   public:
  34.     friend ostream& operator<<( ostream&, const foo& );
  35. };
  36.  
  37. Now, this friend function provides stream io to *any* kind of ostream
  38. for class foo.  That is, you can stream out to the console cout, a file
  39. via an ofstream, an in-memory buffer via an ostrstream, etc.
  40.  
  41.  
  42. OTOH, maybe you want to do something like:
  43.  
  44. class foo {
  45.   public:
  46.     virtual ~foo() {}  // always if deriving!!!
  47.     inline friend ostream& operator<<( ostream&, const foo& );
  48.   protected:
  49.     virtual ostream& virtOut( ostream& ) const;
  50. };
  51.  
  52. ostream& operator<<( ostream& o, const foo& f ) {
  53.     return f.virtOut( o ); }
  54.  
  55. ostream& foo::virtOut( ostream& o ) const {
  56.     return o << "I'm a foo!"; }
  57.  
  58. class bar : public foo {
  59.   protected:
  60.     virtual ostream& virtOut( ostream& ) const;
  61. };
  62.  
  63. ostream& bar::virtOut( ostream& o ) const {
  64.     return o << "I'm a bar!"; }
  65.  
  66.  
  67. Now, each derived class of foo gets to define its own virtOut() function
  68. and that is the one that is used when an object is streamed out.  All <<
  69. operations go through the base class where they pick up virtual function
  70. dispatch... (very handy actually)  BTW, now each derived class controls
  71. it's streaming, *and* it can be streamed to any ostream, cout, ofstream,
  72. ostrstream...  See why streams are so much more powerful than printf()
  73. ???
  74.  
  75.  
  76. -- 
  77.  
  78. Phil Staite, (507) 253-2529, team OS/2
  79. internet: pstaite@vnet.ibm.com  internal: pstaite@rchland
  80.